package tt.dz.egobus.servicemanager.base.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import tt.dz.egobus.servicemanager.core.exception.BusinessException;
import tt.dz.egobus.servicemanager.core.exception.SessionTimeoutException;
import tt.dz.egobus.servicemanager.core.interceptor.JsonSessionHandlerInterceptor;
import tt.dz.egobus.servicemanager.core.interceptor.RequestLoggerInterceptor;
import tt.dz.egobus.servicemanager.core.resovler.ExceptionMappingExceptionResolver;

import java.io.IOException;
import java.util.Properties;

/**
 * Created by anson-worker on 17-2-28.
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "tt.dz.egobus.servicemanager", useDefaultFilters = false,
        includeFilters = {@ComponentScan.Filter(value = {Controller.class, RestController.class})})
@PropertySource({"classpath:properties/view.properties"})
@EnableAspectJAutoProxy
public class MVCConfig extends WebMvcConfigurerAdapter {


    protected Logger log = LoggerFactory.getLogger(getClass());

    {
        log.info(getClass().getName() + " 的对象初始化 .....");
    }

    @Autowired
    private Environment env;

    /**
     * 将对于静态资源的请求转发到Servlet容器的默认处理静态资源的servlet
     * 因为将spring的拦截模式设置为"/"时会对静态资源进行拦截
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    /**
     * 静态资源过滤
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/static/");
        registry.addResourceHandler("/resource/**").addResourceLocations("/resource/");
        registry.addResourceHandler("/DatePicker/**").addResourceLocations("/DatePicker/");
        registry.addResourceHandler("/ext-3.0.3/**").addResourceLocations("/ext-3.0.3/");
        registry.addResourceHandler("/echarts/**").addResourceLocations("/echarts/");
        registry.addResourceHandler("/**/*.css",
                "/login.html",
                "/**/*.ico",
                "/**/*.js"
        ).addResourceLocations("/");
    }

    /**
     * 添加拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestLoggerInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new JsonSessionHandlerInterceptor())
                .excludePathPatterns
                        ("/static*/**", "/web/login", "/error*/**").addPathPatterns("/**");
    }

    /**
     * @param registry
     * @author Anson
     * @date 17-4-19
     * @name view的控制转发
     * @since 1.0.4
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("forward:/login.html");
    }

    /**
     * json 解决方案
     * 用于支持RequestBody 和ResponseBody
     *
     * @return
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter bean = new MappingJackson2HttpMessageConverter();
        return bean;
    }

    /**
     * jsp 试图解决方案
     * order 属性用来解决多视图解决方案
     *
     * @return
     */
    @Bean
    public InternalResourceViewResolver internalResourceViewResolver() {
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setViewClass(JstlView.class);
        bean.setPrefix(env.getProperty("view.settings.prefix", "/WEB-INF/jsp/"));
        bean.setSuffix(env.getProperty("view.settings.suffix", ".jsp"));
        bean.setContentType("text/html;charset=UTF-8");
        return bean;
    }

    /**
     * 附件Multipart解决方案
     *
     * @return
     */
    @Bean
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver bean = new CommonsMultipartResolver();
        bean.setDefaultEncoding("utf-8");
        bean.setMaxUploadSize(10 * 1024 * 1024);//10M
        return bean;
    }

    /**
     * 系统运行时遇到指定的异常将会跳转到指定的页面
     *
     * @return
     */
    @Bean(name = "exceptionResolver")
    public ExceptionMappingExceptionResolver simpleMappingExceptionResolver() {
        ExceptionMappingExceptionResolver simpleMappingExceptionResolver = new ExceptionMappingExceptionResolver();
        String errorDir = "error";

        String loginURL = "/web/login";

        //默认异常试图
        String defaultModelView = errorDir + "/404";
        simpleMappingExceptionResolver.setDefaultErrorView(defaultModelView);
        simpleMappingExceptionResolver.setExceptionAttribute("exception");

        Properties execeptionProperties = new Properties();
        execeptionProperties.setProperty(SessionTimeoutException.class.getName(), loginURL);
        execeptionProperties.setProperty(RuntimeException.class.getName(), errorDir + "/runtimeexp");
        execeptionProperties.setProperty(IOException.class.getName(), errorDir + "/ioexp");
        execeptionProperties.setProperty(BusinessException.class.getName(),
                errorDir + "/common_error");
        simpleMappingExceptionResolver.setExceptionMappings(execeptionProperties);


        Properties statusProperties = new Properties();
        statusProperties.setProperty(defaultModelView, "404");
        statusProperties.setProperty(errorDir + "/500", "500");
        simpleMappingExceptionResolver.setStatusCodes(statusProperties);
        return simpleMappingExceptionResolver;
    }
}
